﻿using System;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

namespace HEFramework
{
    /// <summary>
    ///
    /// HTTP网络类
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2022-6-29 11:08:46
    /// ----------------------------------------
    /// </summary>
    public class HTTP
    {
        /// <summary>
        /// 请求超时时间（S）
        /// </summary>
        private const int HTTP_TIMEOUT_SECOND = 30;

        /// <summary>
        /// 编码类型
        /// </summary>
        private static UTF8Encoding UTF8 = new(false);


        /// <summary>
        /// Post请求
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_json"></param>
        /// <param name="_callback"></param>
        public static void Post(string _url, string _json, Action<int, string> _callback)
        {
            var request = new UnityWebRequest(_url, "POST");
            request.timeout = HTTP_TIMEOUT_SECOND;
            byte[] postBytes = UTF8.GetBytes(_json);
            request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
            request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            var op = request.SendWebRequest();
            op.completed += _ =>
            {
                int code = (int)request.responseCode;
                string data = string.Empty;
                if (Result(request, _url))
                {
                    if (request.downloadHandler != null)
                    {
                        data = request.downloadHandler.text;
                    }
                }

                request.Dispose();
                _callback?.Invoke(code, data);
            };
        }

        /// <summary>
        /// Post请求
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_json"></param>
        /// <returns></returns>
        public static async HETask<string> Post(string _url, string _json)
        {
            var request = new UnityWebRequest(_url, "POST");
            request.timeout = HTTP_TIMEOUT_SECOND;
            byte[] postBytes = UTF8.GetBytes(_json);
            request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
            request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            await request.SendWebRequest();
            string data = string.Empty;
            if (Result(request, _url))
            {
                if (request.downloadHandler != null)
                {
                    data = request.downloadHandler.text;
                }
            }

            request.Dispose();
            return data;
        }

        /// <summary>
        /// Post请求（表单数据形式）
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_form"></param>
        /// <param name="_callback"></param>
        public static void Post(string _url, WWWForm _form, Action<int, string> _callback)
        {
            var request = UnityWebRequest.Post(_url, _form);
            request.timeout = HTTP_TIMEOUT_SECOND;
            var op = request.SendWebRequest();
            op.completed += _ =>
            {
                int code = (int)request.responseCode;
                string data = string.Empty;
                if (Result(request, _url))
                {
                    if (request.downloadHandler != null)
                    {
                        data = request.downloadHandler.text;
                    }
                }

                request.Dispose();
                _callback?.Invoke(code, data);
            };
        }

        /// <summary>
        /// Post请求（表单数据形式）
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_form"></param>
        public static async HETask<string> Post(string _url, WWWForm _form)
        {
            var request = UnityWebRequest.Post(_url, _form);
            request.timeout = HTTP_TIMEOUT_SECOND;
            await request.SendWebRequest();
            string data = string.Empty;
            if (Result(request, _url))
            {
                if (request.downloadHandler != null)
                {
                    data = request.downloadHandler.text;
                }
            }

            request.Dispose();
            return data;
        }

        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="_url"></param>
        /// <param name="_callback"></param>
        public static void Get(string _url, Action<int, byte[]> _callback)
        {
            var request = UnityWebRequest.Get(_url);
            request.timeout = HTTP_TIMEOUT_SECOND;
            var op = request.SendWebRequest();
            op.completed += (_) =>
            {
                int code = (int)request.responseCode;
                byte[] bytes = Array.Empty<byte>();
                if (Result(request, _url))
                {
                    if (request.downloadHandler != null)
                    {
                        if (request.downloadHandler.data != null)
                        {
                            bytes = request.downloadHandler.data;
                        }
                    }
                }

                request.Dispose();
                _callback?.Invoke(code, bytes);
            };
        }

        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="_url"></param>
        public static async HETask<byte[]> Get(string _url)
        {
            var request = UnityWebRequest.Get(_url);
            request.timeout = HTTP_TIMEOUT_SECOND;
            await request.SendWebRequest();
            byte[] bytes = Array.Empty<byte>();
            if (Result(request, _url))
            {
                if (request.downloadHandler != null)
                {
                    if (request.downloadHandler.data != null)
                    {
                        bytes = request.downloadHandler.data;
                    }
                }
            }

            request.Dispose();
            return bytes;
        }

        /// <summary>
        /// 请求结果
        /// </summary>
        /// <param name="_request"></param>
        /// <param name="_url"></param>
        private static bool Result(UnityWebRequest _request, string _url)
        {
            switch (_request.result)
            {
                case UnityWebRequest.Result.ConnectionError:
                    Log.Error($" [{_url}] [ConnectionError] [{_request.error}] [Code: {_request.responseCode}]");
                    return false;
                case UnityWebRequest.Result.DataProcessingError:
                    Log.Error($" [{_url}] [DataProcessingError] [{_request.error}] [Code: {_request.responseCode}]");
                    return false;
                case UnityWebRequest.Result.ProtocolError:
                    Log.Error($" [{_url}] [ProtocolError] [{_request.error}] [Code: {_request.responseCode}]");
                    return false;
                case UnityWebRequest.Result.Success:
                    Log.Debug($" [{_url}] [Success] [Code: {_request.responseCode}]");
                    return true;
            }

            return false;
        }
    }
}